import { FeatureManager, InvokeCmdFunc } from '@amcax/base';
import { PlusOutlined } from '@ant-design/icons';
import { cmdConstrain } from '@app-cad-env/product/commands/cmd-constrain';
import { ConstraintType } from '@app-cad-env/product/commands/cmd-constrain/type';
import { assemblyNodeTitleModifier } from '@app-cad/common/utils/assembly-utils/AssemblyNodeTitleFuncs';
import { personalWorkspaceDocsInfo } from '@app-cad/pages/product-support/assembly-funcs';
import { Button, Dropdown, MenuProps } from 'antd';
import queryString from 'query-string';
import { Dispatch, SetStateAction, useEffect, useRef } from 'react';

import { cmdCircularArray } from '../../commands/cmd-array-circle';
import { cmdLinearArray } from '../../commands/cmd-array-linear';
import { ProductTreeNode } from './types';

interface AssemblyNodeTitleProps {
  nodeData: ProductTreeNode;
  isRoot: boolean;
  setNewDocModalOpen: Dispatch<SetStateAction<boolean>>;
  setInsertDocModalOpen: Dispatch<SetStateAction<boolean>>;
  invokeCmd: InvokeCmdFunc;
  docTree: ProductTreeNode;
}

const AssemblyNodeTitle = ({
  nodeData,
  isRoot,
  setNewDocModalOpen,
  setInsertDocModalOpen,
  invokeCmd,
  docTree,
}: AssemblyNodeTitleProps) => {
  const titleElement = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const nodeElement = titleElement.current.parentElement?.parentElement;
    const openDoc = async () => {
      if (
        nodeData.type === 'assembly-constraint' &&
        nodeData.originalObj.type !== ConstraintType.Fix
      ) {
        await invokeCmd(cmdConstrain, nodeData.originalObj as any);
        return;
      }

      if (nodeData.type === 'array' && nodeData.parent === docTree) {
        const props = {
          ...nodeData.assembly,
          dxid: nodeData.key,
        } as any;

        switch ((nodeData.assembly.params as any).mode) {
          case 'linear':
            await invokeCmd(cmdLinearArray, props);
            return;
          case 'circle':
            await invokeCmd(cmdCircularArray, props);
            return;
        }
        return;
      }

      if (!isRoot && ['product', 'part'].includes(nodeData.type)) {
        if (nodeData.assembly.docid && nodeData.assembly.docver) {
          const url = `?${queryString.stringify({
            col: nodeData.collectionUUID,
            doc: nodeData.assembly.docid,
            ver: nodeData.assembly.docver,
          })}`;
          if (window.__MICRO_APP_ENVIRONMENT__) {
            (window as any).microApp.getGlobalData().history.push(url);
          } else {
            window.open(url, '_blank');
          }
        }
      }
    };

    nodeElement?.addEventListener('dblclick', openDoc);

    return () => {
      nodeElement?.removeEventListener('dblclick', openDoc);
    };
  }, []);

  const docName = personalWorkspaceDocsInfo.find(
    ({ documentUuid }) => documentUuid === nodeData.assembly?.docid,
  )?.name;

  const items: MenuProps['items'] = [
    {
      key: '1',
      label: '新建零部件',
      onClick: () => setNewDocModalOpen(true),
    },
    {
      key: '2',
      label: '插入零部件',
      onClick: () => setInsertDocModalOpen(true),
    },
  ];

  return (
    <div
      className='flex justify-between'
      ref={titleElement}
    >
      <span className={nodeData.visible ? '' : 'product-tree-node-invisible'}>
        {assemblyNodeTitleModifier(nodeData.title, docName)}
      </span>
      {isRoot && FeatureManager.isFeatureEnabled('assemble') && (
        <Dropdown
          menu={{ items }}
          trigger={['click']}
        >
          <Button
            icon={<PlusOutlined />}
            type='text'
            size='small'
          />
        </Dropdown>
      )}
    </div>
  );
};

export const NodeTitle = (
  nodeData: ProductTreeNode,
  isRoot: boolean,
  setNewDocModalOpen: Dispatch<SetStateAction<boolean>>,
  setInsertDocModalOpen: Dispatch<SetStateAction<boolean>>,
  invokeCmd: InvokeCmdFunc,
  docTree: ProductTreeNode,
) => {
  return (
    <AssemblyNodeTitle
      nodeData={nodeData}
      isRoot={isRoot}
      setNewDocModalOpen={setNewDocModalOpen}
      setInsertDocModalOpen={setInsertDocModalOpen}
      invokeCmd={invokeCmd}
      docTree={docTree}
    />
  );
};
